package levelloader
{
	import flash.display.Bitmap;
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	
	import starling.display.Image;
	import starling.display.Sprite;
	import starling.events.Event;

	/**
	 * @author shaun.mitchell
	 */
	public class TiledMap extends Sprite
	{
		// The TMX file to load
		private var _fileName:String;
		private var _loader:URLLoader;
		// XML of TMX file
		private var _TMX:XML;
		// Layers and tilesheet holders
		private var _layers:Vector.<LayerData>;
		private var _objectGroups:Vector.<ObjectLayerData>;
		// variables pertaining to map description
		private var _numLayers:uint;
		private var _numObjectGroups:uint;
		private var _mapWidth:uint;
		private var _mapHeight:uint;
		private var _tileHeight:uint;
		private var _tileWidth:uint;
		
		public var tileMapper:Array;

		public function TiledMap():void
		{
			_fileName = "";
			_loader = new URLLoader();
			_numLayers = 0;
			_numObjectGroups = 0;
			_mapWidth = 0;
			_mapHeight = 0;
			_tileHeight = 0;
			_tileWidth = 0;

			_layers = new Vector.<LayerData>();
			_objectGroups = new Vector.<ObjectLayerData>();
		}

		public function load(file:String):void
		{
			_fileName = file;
			
			trace(_fileName);

			_loader.addEventListener(flash.events.Event.COMPLETE, onExternalMapFileLoaded);
			_loader.load(new URLRequest(_fileName));
		}

		public function loadMap():void
		{			 
			_TMX = new XML(new Assets[Assets.SEASONS_MAPS[(Game.season-1)*3 + Game.level]]());

			loadMapProperties();
		}

		// Getters ------------------------------------------
		public function layers():Vector.<LayerData>
		{
			return _layers;
		}

		public function objectGroups():Vector.<ObjectLayerData>
		{
			return _objectGroups;
		}

		public function numLayers():uint
		{
			return _numLayers;
		}

		public function numObjectGroups():uint
		{
			return _numObjectGroups;
		}

		public function mapWidth():uint
		{
			return _mapWidth;
		}

		public function mapHeight():uint
		{
			return _mapHeight;
		}

		public function tileHeight():uint
		{
			return _tileHeight;
		}

		public function tileWidth():uint
		{
			return _tileWidth;
		}

		// End getters --------------------------------------
		// get the number of layers from the TMX XML
		private function getNumLayers():uint
		{
			var count:uint = 0;
			for (var i:int = 0; i < _TMX.children().length(); i++)
			{
				if (_TMX.layer[i] != null)
				{
					count++;
				}
			}
			
			trace(count);
			return count;
		}
		
		// get the number of objectgroups from the TMX XML
		private function getNumObjectGroups():uint
		{
			var count:uint = 0;
			for (var i:int = 0; i < _TMX.children().length(); i++)
			{
				if (_TMX.objectgroup[i] != null)
				{
					count++;
				}
			}
			
			trace(count);
			return count;
		}
		
		private function onExternalMapFileLoaded(event:flash.events.Event):void
		{
			_TMX = new XML(_loader.data);
			
			loadMapProperties();
		}

		private function loadMapProperties():void
		{
			if (_TMX)
			{
				_mapWidth = _TMX.@width;
				_mapHeight = _TMX.@height;
				_tileHeight = _TMX.@tileheight;
				_tileWidth = _TMX.@tilewidth;

				trace("map width" + _mapWidth);
				trace("map height" + _mapHeight);

				_numLayers = getNumLayers();				
				_numObjectGroups = getNumObjectGroups();
				
				tileMapper = new Array();
				var idx:uint = 0;
				tileMapper[idx++] = "";
				for each(var tileset:Object in _TMX.tileset)
				{
					tileMapper[idx++] = String(tileset.@name); 
				}
				
				// _TMX.properties.property[1].@value;				
				loadMapData();
			}
		}


		private function loadMapData():void
		{
			for (var i:int = 0; i < _numLayers; i++)
			{
				trace("loading map data");
				var ba:ByteArray = CustomBase64Decoder.decode(_TMX.layer[i].data);
				ba.uncompress();
				
				var data:Array = new Array();
				
				for (var j:int = 0; j < ba.length; j += 4)
				{
					// Get the grid ID
					
					var a:int = ba[j];
					var b:int = ba[j + 1];
					var c:int = ba[j + 2];
					var d:int = ba[j + 3];
					
					var gid:int = a | b << 8 | c << 16 | d << 24;
					data.push(gid);
				}
				
				var tmxLayer:LayerData = new LayerData(data, this);
				
				_layers.push(tmxLayer);
			}
			
			for(var idx:uint = 0; idx < _numObjectGroups; ++idx)
			{
				var tmxObjectGroup:ObjectLayerData = new ObjectLayerData(_TMX.objectgroup[idx]);
				_objectGroups.push(tmxObjectGroup);
			}
			
			// notify that the load is complete
			dispatchEvent(new starling.events.Event(starling.events.Event.COMPLETE));
		}
	}
}